///////////////////////////////////////////////////////////////////////////////
/** \file 
 *  \brief 
 **/ 
///////////////////////////////////////////////////////////////////////////////

#ifndef PrimaryGeneratorAction_h
#define PrimaryGeneratorAction_h 1

#include "G4VUserPrimaryGeneratorAction.hh"
#include "G4Event.hh"
#include "G4ParticleGun.hh"
#include "G4ThreeVector.hh"
#include "G4RotationMatrix.hh"
#include "G4ParticleTable.hh"
#include "G4DecayTable.hh"
#include "G4BetaMinusDecayChannel.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
#include "G4Triton.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "globals.hh"

#include "TFile.h"
#include "TGraph.h"
#include "TSpline.h"
#include "TF1.h"
#include "TMath.h"
#include "TRandom.h"

#include "MBglobals.hh"
#include "MiniBallSource.hh"

#include "Randomize.hh"

#include "Kinematic.hh"

#include "HistoManager.hh"
#include "Data.hh"

class G4ParticleGun;
class G4Event;

class PrimaryGeneratorAction : public MiniBallSource
{
public:
  PrimaryGeneratorAction(HistoManager*, Data*);
  ~PrimaryGeneratorAction();
  
public:
  void GeneratePrimaries(G4Event* anEvent);

  void BeamParticles();

private:

  void CreateSplines(G4String);
  void CreateOpticalPotential(G4String);

  G4double Integrate(G4int, G4double*, G4double*, G4int);

  void SetThetaLab(double[]);
    
  void MinimalThetaCm(double[],double[]);
  void MaximalThetaCm(double[],double[]);
    
  int ReactionType();
    
  double ExcitationEnergy(int);
    
  void ThetaCm(int, double);
    
  void ElasticTarget(int, Element*&);

  G4ParticleDefinition* Definition(int, int, double);

  G4ParticleGun* particleGun1;
  G4ParticleGun* particleGun2;
  G4ParticleGun* particleGun3;
  G4ParticleGun* particleGun4;

  HistoManager* histoManager;
  Data* data;

  MiniBallSourceLevel** level;
  Kinematic* kinematics;
  TSpline3* EVsX;
  TSpline3* RVsX;
  TGraph** AngularDistribution;
  TGraph** OpticalPotential;
  G4double* MaxAngularDistribution;
  G4double* MaxOpticalPotential;
  G4double* CrossSectionIntegral;
  G4double* ICrossSectionIntegral;
  G4double* ArealDensity;
  G4double* ScatteringProbability;
  G4double MaxRutherford;
  G4double EfficiencyEnergy[8];
  G4double* part_sum;
  G4double sum;
  G4double* RutherfordFactor;
  G4double* E_cm;
  G4double* ThetaCmMin;
  G4double* ThetaCmMax;
  G4double IntThetaCmMin;
  G4double IntThetaCmMax;

  G4ParticleTable* particleTable;

  ofstream file;
};

#endif


